package com.chizha.iot.mqtt.server;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.xml.ws.Response;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chizha.common.HexDump;
import com.chizha.iot.mqtt.client.ServerMQTT;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Record;

public class MessageHandleController {

	private static final String PICTURE_PATH = "/home/dws_2016/";
	private static final String DOWN_MSG_TOPIC = "/msgdown";
	private static final String DOWN_PIC_TOPIC = "/picdown";
	private static Log logger = Log.getLog(MessageHandleController.class);
	private static Map<String,byte[]> picmap = new HashMap<String, byte[]>();

	//private Map<String, ServerMQTT> picMqttMap = new ConcurrentHashMap<String, ServerMQTT>();
	private static MessageHandleController instance = new MessageHandleController();
	private MessageHandleController()
	{
		
	}
	public static MessageHandleController getInstance()
	{
		return instance;
	}
	MessageHandleService messageHandleService = new MessageHandleService();
static int packet_size = 0;
	//arrived mqtt msg (相机 --> 服务器)
	public void arrivedMqttMsg(String topicName, byte[] rawData) {
		try {
			
			String messageType = "";

			
			
			String[] topicNameArr = topicName.split("/");
			String terminal_id = topicNameArr[0];
			
			Map<String, Object> mqttDownMap = new HashMap<String, Object>();
			
			//相机 --> 服务器, 图片发送与确认, 例：topicName : A129FB112111/picup 
			if(topicName.endsWith("picup")){
				logger.info("-----------picup-------------" + topicName);
				messageType = "picup";
				/*byte[] packet_data = rawData;//本次图片数据
				byte[] lastTotalPicbytes = picmap.get(terminal_id);//前面几个包的数据和
				log.info("first ------------------" + picmap.get(terminal_id) + "-------------------");
				if (lastTotalPicbytes == null){
					lastTotalPicbytes = new byte[0];
				}
				log.info("lastTotalPicbytes length : -----------" + lastTotalPicbytes.length + "---------------");
				byte[] totalPicBytes = new byte[rawData.length + lastTotalPicbytes.length];//所有包的数据和
				System.arraycopy(lastTotalPicbytes, 0, totalPicBytes, 0, lastTotalPicbytes.length);  
			    System.arraycopy(packet_data, 0, totalPicBytes, lastTotalPicbytes.length, packet_data.length);
			    picmap.put(terminal_id, totalPicBytes);
			    log.info("9999999999----------------" + picmap.get(terminal_id).length + "-------------------------------");
				log.info("---------" + totalPicBytes.length + "------------------------------");
				if(totalPicBytes.length > 100){
					String picPath = "E:/animalPic/"+System.currentTimeMillis()+".doc";//新生成的图片  
		            OutputStream out = new FileOutputStream(picPath);      
		            out.write(totalPicBytes);  
		            out.flush();  
		            out.close();
		            File imgFile = new File(picPath);

					log.info("picup------------333------------");
		            messageHandleService.savePicPath(terminal_id, imgFile.getPath());
					picmap.remove(terminal_id);
					log.info(imgFile.getPath());
				}*/
				logger.info(HexDump.toHexString(rawData));
				
				byte start_byte1 = rawData[0]; //起始字节   固定为0xa596
				byte start_byte2 = rawData[1];
				if (((0xFF&start_byte1) != 0xa5) || ((0xFF&start_byte2) != 0x96))
				{
					logger.error("error start code, 1:"+start_byte1 + " 2:"+start_byte2);
					//return;
				}
				int picture_id = ((0xFF&rawData[2])<<8) + (0xFF&rawData[3]);//图片序列，重新传输需要自动加1
				int packet_total_num = ((0xFF&rawData[4])<<8) + (0xFF&rawData[5]);//一共分成多少包
				int packet_id = ((0xFF&rawData[6])<<8) + (0xFF&rawData[7]);//本包图片的ID
				int data_length = ((0xFF&rawData[8])<<8) + (0xFF&rawData[9]);//本包数据长度
				int data_total_length = (rawData[10]<<24) + ((0xFF&rawData[11])<<16) + ((0xFF&rawData[12])<<8) + (0xFF&rawData[13]);//图片数据长度
//				logger.info("rawData[10]:" + rawData[10]);
//				logger.info("rawData[11]:" + rawData[11]);
//				logger.info("rawData[12]:" + rawData[12]);
//				logger.info("rawData[13]:" + rawData[13]);
				byte[] packet_data = new byte[data_length];//本次图片数据
				for (int i = 0; i < packet_data.length; i++) {
					packet_data[i] = rawData[14 + i];
				}
				
				byte[] totalPicBytes = picmap.get(terminal_id);//前面几个包的数据和
				//byte[] totalPicBytes = new byte[data_total_length];//所有包的数据和
				
				if (totalPicBytes == null){
					totalPicBytes = new byte[(int) data_total_length];
					picmap.put(terminal_id, totalPicBytes);
				}
				int data_length2 = data_length;
				if (packet_size >  data_length2)
				{
					data_length2 = packet_size;
				}else
				{
					packet_size = data_length2;
				}
				int alreadysent = data_length2 * packet_id; //(data_total_length / packet_total_num)
				logger.info("data_total_length:" + data_total_length);
				logger.info("packet_total_num:" + packet_total_num);
				logger.info("packet_id:" + packet_id);
				logger.info("alreadysent:" + alreadysent);
				System.arraycopy(packet_data, 0, totalPicBytes, (int) alreadysent , packet_data.length);
				
				/*int packet_avg_len = data_total_length / packet_total_num;//每包数据长度
				
				for(int i = 0; i < data_length; i++){
					picbytes[i + packet_id * packet_avg_len] = rawData[28 + i];
				}*/
				
			    
			    //
			    
			    //------------Send to confirm ---------------------------
				ServerMQTT mqttserver = new ServerMQTT(terminal_id + DOWN_PIC_TOPIC);
			
				mqttDownMap.put("start_byte", "0xa596");
				mqttDownMap.put("picture_id", picture_id);
				byte[] Response = new byte[4];
				Response[0] = (byte) 0xa5;
				Response[1] = (byte) 0x96;
				Response[2] = rawData[2];
				Response[3] = rawData[3];
				
				mqttserver.publishTopic(Response);
				
				//--------------------get last packet of picture--------------------
				if (packet_id ==  packet_total_num-1){
		            String picPath = PICTURE_PATH + "pic"+picture_id +".jpg";//新生成的图片  
		            OutputStream out = new FileOutputStream(picPath);      
		            out.write(totalPicBytes);  
		            out.flush();  
		            out.close();
		            File imgFile = new File(picPath);
		            
		            messageHandleService.savePicPath(terminal_id, imgFile.getPath());
					picmap.remove(terminal_id);
					
				}
				messageHandleService.saveRawData("mqttmsg", messageType, topicName, HexDump.toHexString(rawData),JSONObject.toJSONString(mqttDownMap));
			}
			
			if(topicName.endsWith("msgup")){
				logger.info("------------MsgUp-----------------");
				logger.info(topicName + (new String(rawData)));
				
				JSONObject objData = JSONObject.parseObject(new String(rawData));
				if (objData == null)
				{
					logger.error("mqtt message is null.");
					return;
				}
				messageType = (String) objData.get("mt");//消息类型
				//相机 --> 服务器, 定时请求任务消息与回复, 例：topicName : A129FB112111/msgup,"mt":"trep", 
				if(messageType.equals("treq")){
					//find the task from db and send to terminal
					Record taskList = messageHandleService.findTask(terminal_id);
					
					JSONArray b = JSONObject.parseArray(taskList.get("task_list"));
					JSONObject jobj = new JSONObject();
					jobj.put("mt", "tresp");
					jobj.put("t_id", taskList.get("task_id"));
					jobj.put("tlist", b);
					ServerMQTT mqttDown = new ServerMQTT(terminal_id+DOWN_MSG_TOPIC);
					mqttDown.publishTopic( jobj);
				}
				
				//相机 --> 服务器, 定时发送传感器消息, 例：topicName : A129FB112111/msgup, "mt":"sdata", 
				if(messageType.equals("sdata")){
					String sid = (String) objData.get("sid");//传感器数据编号
					
					//TODO
					//save to database of the sensor
					mqttDownMap.put("mt", "sdataresp");
					mqttDownMap.put("sid", sid);
					ServerMQTT mqttDown = new ServerMQTT(terminal_id+DOWN_MSG_TOPIC);
					mqttDown.publishTopic(mqttDownMap);
				}
				messageHandleService.saveRawData("mqttmsg", messageType, topicName, new String(rawData), JSONObject.toJSONString(mqttDownMap));//向数据库插入一条数据
				
			}
			
			//ServerMQTT.publishTopic(topicName.replaceAll("up", "down"), mqttDownMap);
			
		} catch (Exception e) {
			logger.error(e.toString(),e);
		}
	}

}
